%include "syscalls.asm"
%include "nl.asm"
%include "print_pointer.asm"
%include "print_type.asm"
%include "print_number.asm"
%include "bltn_cons.asm"
%include "bltn_closure.asm"
%include "heap.asm"
%include "symbol.asm"

section .data
hw	db	"Hello world!"

section .bss	align=8
stack	resq	1024

section	.text
global _start

_start:
	mov	rax, sys_write
	mov	rdi, 0
	mov	rsi, hw
	mov	rdx, 12
	syscall

	call	nl

	mov	rax, stack
	call	print_pointer
	call	nl

	mov	rax, heap1
	call	print_pointer
	call	nl

	mov	rax, heap2
	call	print_pointer
	call	nl

	mov	rax, [heap_ptr]
	call	print_pointer
	call	nl

	mov	rax, [heap_end]
	call	print_pointer
	call	nl

;; TEST CONSING CARING AND CDRING

	mov	rax, 0x0000000000000000 ;bool
	mov	r8,  0x0000000000000008 ;nil
	call	bltn_cons
	
	push	rax
	
	call	print_pointer
	call	nl

	pop	rax
	push	rax
		
	call	print_type

	pop	rax
	push	rax

	call	print_pointer
	call	nl

	pop	rax
	push	rax
	
	call	bltn_car
	call	print_type
	
	pop	rax

	call	bltn_cdr
	call	print_type
	
	call	nl

;; TEST PRINTING OTHER TYPES
	
	mov	rax, 0x0000000000000003 ;closure
	call	print_type

	mov	rax, 1
	call	heap_alloc

	mov	rax, 0x0000000000000007 ;gcredir
	call	print_type

	mov	rax, 1
	call	heap_alloc

	mov	rax, 0x0000000000000010 ;symbol
	call	print_type

	mov	rax, 1
	call	heap_alloc

	mov	rax, 0x0000000000000018 ;char
	call	print_type
	
	call	nl

;; TEST PRINTING A NUMBER

	mov	rax, 228298597
	shl	rax, 3
	or	rax, 0b001
	
	call	print_number
	
	call	nl

;; TEST BUILTING UP A LIST
	
	mov	rax,  0x0000000000000008 ;nil
	
	mov	r8, rax
	mov	rax, 44
	shl	rax, 3
	or	rax, 0b001
	call	bltn_cons

	mov	r8, rax
	mov	rax, 33
	shl	rax, 3
	or	rax, 0b001
	call	bltn_cons

	mov	r8, rax
	mov	rax, 772277
	shl	rax, 3
	or	rax, 0b001
	call	bltn_cons

	mov	r8, rax
	mov	rax, 668899
	shl	rax, 3
	or	rax, 0b001
	call	bltn_cons

	mov	r8, rax
	mov	rax, 123456
	shl	rax, 3
	or	rax, 0b001
	call	bltn_cons

	push	rax
	call	bltn_car
	call    print_number
	call	nl
	pop	rax

	push	rax
	call	bltn_cdr
	call	bltn_car
	call    print_number
	call	nl
	pop	rax

	push	rax
	call	bltn_cdr
	call	bltn_cdr
	call	bltn_car
	call    print_number
	call	nl
	pop	rax

	push	rax
	call	bltn_cdr
	call	bltn_cdr
	call	bltn_cdr
	call	bltn_car
	call    print_number
	call	nl
	pop	rax

	push	rax
	call	bltn_cdr
	call	bltn_cdr
	call	bltn_cdr
	call	bltn_cdr
	call	bltn_car
	call    print_number
	call	nl
	pop	rax


;;; SYMBOLS

	mov	rax, 0x0000000000000010 ;symbol
	call	display_symbol
	call	nl

	mov	rax, 1
	shl	rax, 5
	or	rax, 0x0000000000000010 ;symbol
	call	display_symbol
	call	nl

	mov	rax, 2
	shl	rax, 5
	or	rax, 0x0000000000000010 ;symbol
	call	display_symbol
	call	nl

	mov	rax, 3
	shl	rax, 5
	or	rax, 0x0000000000000010 ;symbol
	call	display_symbol
	call	nl

;	mov	rax, 4
;	shl	rax, 5
;	or	rax, 0x0000000000000010 ;symbol
;	call	display_symbol
;	call	nl

;;; CLOSURE

	;; aloc one
	mov	rax, 2
	mov	r8, .clo1
	call	bltn_alloc_closure
	
	push	rax

	;; set its env up
	mov	rax, 0x0000000000000010 ;symbol
	mov	r8, rax
	pop	rax
	push	rax
	mov	rcx, 2
	mov	[rax + 8*rcx], r8

	mov	rax, 1
	shl	rax, 5
	or	rax, 0x0000000000000010 ;symbol
	mov	r8, rax
	pop	rax
	push	rax
	mov	rcx, 3
	mov	[rax + 8*rcx], r8


	;; just print it for now
	pop	rax
	call	print_type
	call 	nl

	mov	rax, sys_exit
	mov	rdi, 0
	syscall


.clo1:
	mov	rax, sys_exit
	mov	rdi, 0
	syscall

	ret
